package com.unism.common.aop.sso.socket;

import java.util.*;
import java.net.*;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.unism.common.sso.commu.udpServer.*;

import java.io.*;

public class UdpSendManager extends Thread {
	private static UdpSendManager instance;
	private static UdpSendSocket socket;
	private static Object synObj = new Object();
	private static ArrayList<UdpData> list = new ArrayList<UdpData>();

	private static Logger log = LoggerFactory.getLogger(UdpSendManager.class.getName());

	private UdpSendManager(int port, int timeOut) throws SocketException {
		socket = new UdpSendSocket(port, timeOut);
	}

	/**
	 * 只进行一次初始化
	 * 
	 * @return
	 * @throws Exception
	 */
	public static void initFirst(int port, int timeOut) throws SocketException {
		instance = new UdpSendManager(port, timeOut);
	}

	/**
	 * 得到唯一实例
	 * 
	 * @return
	 * @throws Exception
	 */
	public static UdpSendManager singleInstance() throws Exception {
		if (instance == null) {
			throw new Exception("请首先初始化" + UdpSendManager.class.getName() + "类实例！");
		}
		return instance;
	}

	/**
	 * 发送数据
	 * 
	 * @param obj
	 * @param ip
	 * @param port
	 * @throws Exception
	 */
	public void setSendObject(UdpData d) throws Exception {
		if (d == null || d.receiveIp == null || d.receivePort == null || d.obj == null) {
			throw new Exception("UDP网络输出数据不完整！");
		}
		synchronized (synObj) {
			list.add(d);
			synObj.notifyAll();
		}
	}

	/**
	 * 逻辑方法
	 */
	public void run() {
		while (true) {
			synchronized (synObj) {
				if (list.size() == 0) {
					try {
						synObj.wait();
					} catch (Exception e) {
						log.error("输出数据线程发生等待异常！");
						continue;
					}
				}

				Iterator<UdpData> it = list.iterator();
				UdpData d = null;
				while (it.hasNext()) {
					d = it.next();
					try {
						ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
						ObjectOutputStream objOut = new ObjectOutputStream(new DataOutputStream(byteOut));
						objOut.writeObject(d);
						socket.send(byteOut.toByteArray(), d.receiveIp, d.receivePort.intValue());

					} catch (Exception e) {
						log.error(e.getMessage(), e);
					}
					it.remove();
				}
			}
		}

	}

}
